#include "networkassistant.h"
#include "ui_networkassistant.h"

NetworkAssistant::NetworkAssistant(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::NetworkAssistant)
{
    ui->setupUi(this);
       /* udp套接字 */
    udpSocket = new QUdpSocket(this);

    /* 设置端口号的范围，注意不要与主机的已使用的端口号冲突 */
    ui->spinBox_10->setRange(1000, 99999);
    ui->spinBox_10->setValue(30301);
    ui->spinBox_9->setRange(1000, 99999);
    ui->spinBox_9->setValue(30300);

    /* 设置停止监听状态不可用 */
    ui->pushButton_26->setEnabled(false);

    /* 设置输入框默认的文本 */
    ui->lineEdit_10->setText("hello V2X!!!");
    ui->lineEdit_9->setText("192.168.62.199");
    
      // 设置窗口透明度
    this->setWindowOpacity(0.96);
    this->setWindowTitle("network assistant");
    // 设置背景图片
    QPixmap pixmap("../res/bg.png");

    ui->background->setPixmap(pixmap.scaled(640,800));

    // 设置窗口样式
    ui->widget->setStyleSheet("QWidget{background-color:rgba(255,255,255,0.6);border-radius:20px;}");
    ui->textBrowser_5->setStyleSheet("QTextBrowser#textBrowser_5{background-color:rgba(255,255,255,0.6);border-radius:20px;}");
        
    /* 获取本地ip */
    getLocalHostIP();

    /* 信号槽连接 */
    connect(ui->pushButton_25, SIGNAL(clicked()),
            this, SLOT(bindPort()));
    connect(ui->pushButton_26, SIGNAL(clicked()),
            this, SLOT(unbindPort()));
    connect(ui->pushButton_27, SIGNAL(clicked()),
            this, SLOT(clearTextBrowser()));
    connect(ui->pushButton_28, SIGNAL(clicked()),
            this, SLOT(sendMessages()));
    connect(ui->pushButton_29, SIGNAL(clicked()),
            this, SLOT(sendBroadcastMessages()));
    connect(ui->pushButton_30, SIGNAL(clicked()),
        this, SLOT(ExitWindow()));
    connect(udpSocket, SIGNAL(readyRead()),
            this, SLOT(receiveMessages()));
    connect(udpSocket,
            SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            this,
            SLOT(socketStateChange(QAbstractSocket::SocketState)));
}
void NetworkAssistant::ExitWindow()
{
    this->parentWidget()->show();
    this->hide();
}

void NetworkAssistant::getLocalHostIP()
{
    /* 获取所有的网络接口，
     * QNetworkInterface类提供主机的IP地址和网络接口的列表 */
    QList<QNetworkInterface> list
            = QNetworkInterface::allInterfaces();

    /* 遍历list */
    foreach (QNetworkInterface interface, list) {

        /* QNetworkAddressEntry类存储IP地址子网掩码和广播地址 */
        QList<QNetworkAddressEntry> entryList
                = interface.addressEntries();

        /* 遍历entryList */
        foreach (QNetworkAddressEntry entry, entryList) {
            /* 过滤IPv6地址，只留下IPv4 */
            if (entry.ip().protocol() ==
                    QAbstractSocket::IPv4Protocol) {
                ui->comboBox_5->addItem(entry.ip().toString());
                /* 添加到IP列表中 */
                IPlist<<entry.ip();
            }
        }
    }
}

void NetworkAssistant::bindPort()
{
    quint16 port = ui->spinBox_10->value();

    /* 绑定端口需要在socket的状态为UnconnectedState */
    if (udpSocket->state() != QAbstractSocket::UnconnectedState)
        udpSocket->close();

    if (udpSocket->bind(port)) {
        ui->textBrowser_5->append("已经成功绑定端口："
                            + QString::number(port));

        /* 设置界面中的元素的可用状态 */
        ui->pushButton_25->setEnabled(false);
        ui->pushButton_26->setEnabled(true);
        ui->spinBox_10->setEnabled(false);
    }
}

void NetworkAssistant::unbindPort()
{
    /* 解绑，不再监听 */
    udpSocket->abort();

    /* 设置界面中的元素的可用状态 */
    ui->pushButton_25->setEnabled(true);
    ui->pushButton_26->setEnabled(false);
    ui->spinBox_10->setEnabled(true);
}

void NetworkAssistant::clearTextBrowser()
{
    /* 清除文本浏览器的内容 */
    ui->textBrowser_5->clear();
}

void NetworkAssistant::receiveMessages()
{
    /* 局部变量，用于获取发送者的IP和端口 */
    QHostAddress peerAddr;
    quint16 peerPort;

    /* 如果有数据已经准备好 */
    while (udpSocket->hasPendingDatagrams()) {
       /* udpSocket发送的数据报是QByteArray类型的字节数组 */
       QByteArray datagram;

       /* 重新定义数组的大小 */
       datagram.resize(udpSocket->pendingDatagramSize());

       /* 读取数据，并获取发送方的IP地址和端口 */
       udpSocket->readDatagram(datagram.data(),
                               datagram.size(),
                               &peerAddr,
                               &peerPort);
       /* 转为字符串 */
       QString str = datagram.data();

       /* 显示信息到文本浏览框窗口 */
       ui->textBrowser_5->append("接收来自"
                           + peerAddr.toString()
                           + ":"
                           + QString::number(peerPort)
                           + str);
    }
}

void NetworkAssistant::sendMessages()
{
    /* 文本浏览框显示发送的信息 */
     ui->textBrowser_5->append("发送：" + ui->lineEdit_10->text());

     /* 要发送的信息，转为QByteArray类型字节数组，数据一般少于512个字节 */
     QByteArray data = ui->lineEdit_10->text().toUtf8();

     /* 要发送的目标Ip地址 */
//     QHostAddress peerAddr = IPlist[ui->comboBox->currentIndex()];
     QString targetIP =  ui->lineEdit_9->text();
     QHostAddress    targetAddr(targetIP);
     /* 要发送的目标端口号 */
     quint16 peerPort = ui->spinBox_9->value();

     /* 发送消息 */
     udpSocket->writeDatagram(data, targetAddr, peerPort);    
}

void NetworkAssistant::sendBroadcastMessages()
{
    /* 文本浏览框显示发送的信息 */
    ui->textBrowser_5->append("发送：" + ui->lineEdit_10->text());

    /* 要发送的信息，转为QByteArray类型字节数组，数据一般少于512个字节 */
    QByteArray data = ui->lineEdit_10->text().toUtf8();

    /* 广播地址，一般为255.255.255.255，
     * 同一网段内监听目标端口的程序都会接收到消息 */
    QHostAddress peerAddr = QHostAddress::Broadcast;

    /* 要发送的目标端口号 */
    quint16 peerPort = ui->spinBox_9->text().toInt();

    /* 发送消息 */
    udpSocket->writeDatagram(data, peerAddr, peerPort);
}

void NetworkAssistant::socketStateChange(QAbstractSocket::SocketState state)
{
switch (state) {
   case QAbstractSocket::UnconnectedState:
       ui->textBrowser_5->append("scoket状态：UnconnectedState");
       break;
   case QAbstractSocket::ConnectedState:
       ui->textBrowser_5->append("scoket状态：ConnectedState");
       break;
   case QAbstractSocket::ConnectingState:
       ui->textBrowser_5->append("scoket状态：ConnectingState");
       break;
   case QAbstractSocket::HostLookupState:
       ui->textBrowser_5->append("scoket状态：HostLookupState");
       break;
   case QAbstractSocket::ClosingState:
       ui->textBrowser_5->append("scoket状态：ClosingState");
       break;
   case QAbstractSocket::ListeningState:
       ui->textBrowser_5->append("scoket状态：ListeningState");
       break;
   case QAbstractSocket::BoundState:
       ui->textBrowser_5->append("scoket状态：BoundState");
       break;
   default:
       break;
   }
}

NetworkAssistant::~NetworkAssistant()
{
    delete ui;
}
